//
//  ZKDownLoadTaskManager.m
//  sensen_ios
//
//  Created by pro on 16/3/30.
//  Copyright © 2016年 pro. All rights reserved.
//

#import "ZKDownLoadTaskManager.h"

@interface ZKDownLoadTaskManager () <NSURLSessionDownloadDelegate>
{
}

@property (nonatomic, strong) NSData *resumeData;
@property (nonatomic, strong) NSURLSession *session;
@property (nonatomic, strong) NSURLSessionDownloadTask *downLoadTask;

@property (nonatomic, strong) NSURLSessionDownloadTask *AFDownLoadTask;


@end

@implementation ZKDownLoadTaskManager

static ZKDownLoadTaskManager *instance;

#pragma mark - 单例
+ (instancetype)manager {
    static dispatch_once_t onceToken;
    
    //这个函数中的代码快任务只能执行一次。他是线程安全的。
    dispatch_once(&onceToken, ^{
        instance = [[self alloc] init];
    });
    return instance;
}
//实现一些限制方法，限制这个类始终只能创建一个对象，并且此对象不能销毁
+ (id)allocWithZone:(struct _NSZone *)zone {
    
    if (instance == nil) {
        instance = [super allocWithZone:zone];
    }
    return instance;
}

#pragma mark - 方法
/*
 直接集成AFNetworking的api，使用NSProgress来获得下载进度
 */
- (void)startAFDownLoadWithUrl:(NSString *)urlStr
                      delegate:(id<ZKDownLoadTaskDelegate>)delegate {
    
    // 设置代理
    self.delegate = delegate;
    
    // 网络管理类
    AFHTTPSessionManager *manager = [AFHTTPSessionManager manager];
    
    // 网络请求类
    NSURLRequest *request = [NSURLRequest requestWithURL:[NSURL URLWithString:urlStr]];
    
    /*
     要跟踪进度，需要使用 NSProgress，是在 iOS 7.0 推出的，专门用来跟踪进度的类！
     NSProgress只是一个对象！如何跟踪进度！-> KVO 对属性变化的监听！
     */
    NSProgress *progress = nil;
    
    // 下载任务，会根据下载进度实时改变 progress 对象的属性
    
    self.AFDownLoadTask = [manager downloadTaskWithRequest:request progress:&progress destination:^NSURL *(NSURL *targetPath, NSURLResponse *response) {

        // 这里设置想要保存文件的路径，并返回，下面的filePath会用到
        NSString *cachesPath = [NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES) lastObject];
        NSString *path = [cachesPath stringByAppendingPathComponent:response.suggestedFilename];

        return [NSURL fileURLWithPath:path];

    } completionHandler:^(NSURLResponse *response, NSURL *filePath, NSError *error) {
        // 文件的绝对路径字符串
        NSLog(@"下载完成:%@",filePath.absoluteString);
    }];
    
    
    // 给Progress添加监听 KVO
    [progress addObserver:self forKeyPath:@"completedUnitCount" options:NSKeyValueObservingOptionNew context:nil];
    
    // 开始任务
    [self.AFDownLoadTask resume];
}

/*
 直接用iOS自带的NSURLSession，可实现断电续传等功能
 */
- (void)startDownLoadWithUrl:(NSString *)urlStr
                    delegate:(id<ZKDownLoadTaskDelegate>)delegate {
    
    if (self.downLoadTask) {
        [self pause];
    } else {
        // 任务已经存在，则是继续下载
        if (self.resumeData != nil) {
            self.downLoadTask = [self.session downloadTaskWithResumeData:_resumeData];
            _resumeData = nil;
        }
        // 否则开启一个新的下载
        else {
            // 设置代理
            self.delegate = delegate;
            
            self.session = [NSURLSession sessionWithConfiguration:[NSURLSessionConfiguration defaultSessionConfiguration] delegate:self delegateQueue:[NSOperationQueue mainQueue]];
            NSURLRequest *request = [NSURLRequest requestWithURL:[NSURL URLWithString:urlStr]];
            self.downLoadTask = [self.session downloadTaskWithRequest:request];
            
            // 开始任务
            [self.downLoadTask resume];
        }
    }
    
}
- (void)pause {
    __weak typeof(self) weakSelf = self;
    [self.downLoadTask cancelByProducingResumeData:^(NSData * _Nullable resumeData) {
        weakSelf.resumeData = resumeData;
        weakSelf.downLoadTask = nil;
    }];
}


#pragma mark - NSURLSessionDownLoadDelegate
// 接收到新数据
- (void)URLSession:(NSURLSession *)session downloadTask:(NSURLSessionDownloadTask *)downloadTask
      didWriteData:(int64_t)bytesWritten totalBytesWritten:(int64_t)totalBytesWritten totalBytesExpectedToWrite:(int64_t)totalBytesExpectedToWrite {
    
    NSLog(@"下载中:%lld, %lld, %lld", bytesWritten, totalBytesWritten, totalBytesExpectedToWrite);
    
}
// 下载完成
- (void)URLSession:(NSURLSession *)session downloadTask:(NSURLSessionDownloadTask *)downloadTask
    didFinishDownloadingToURL:(NSURL *)location {
    
    // 获得保存路径
    NSString *cachesPath = [NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES) firstObject];
    NSString *path = [cachesPath stringByAppendingPathComponent:downloadTask.response.suggestedFilename];
    
    NSError *error;
    if([[NSFileManager defaultManager] moveItemAtPath:location.path toPath:path error:&error]) {
        if (error) {
            NSLog(@"Error:%@", error);
            return;
        }
        NSLog(@"Save success to path:%@", path);
    }
}
// 暂定要执行的方法
- (void)URLSession:(NSURLSession *)session downloadTask:(NSURLSessionDownloadTask *)downloadTask
 didResumeAtOffset:(int64_t)fileOffset
expectedTotalBytes:(int64_t)expectedTotalBytes {
    NSLog(@"暂停时:%lld, %lld", fileOffset, expectedTotalBytes);

}


// 收到通知调用的方法
//- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(NSProgress *)object change:(NSDictionary *)change context:(void *)context
//{
//    
//    if ([keyPath isEqualToString:@"paused"]) {
//        NSLog(@"展厅");
//        return;
//    }
//    
//    CGFloat progress = 1.0 * object.completedUnitCount / object.totalUnitCount;
//    NSLog(@"%f", progress);
//    if (progress>0.1) {
////        [_downLoadTask cancelByProducingResumeData:^(NSData * _Nullable resumeData) {
////
////        }];
//        [object pause];
//    }
//    if ([self.delegate respondsToSelector:@selector(downLoadProgressDidChange:)]) {
//        /*
//         // 在主线程中刷新UI
//         dispatch_async(dispatch_get_main_queue(), ^{
//            
//         });
//         */
//        [self.delegate downLoadProgressDidChange:progress];
//    }
//    
//}

@end
